import { Request, Response } from 'express';
import { AppDataSource } from '../../config/database';
import { PaymentRecord, PaymentStatus, PaymentMethod } from '../../entities/PaymentRecord';
import { Repository, In } from 'typeorm';
import { AuthRequest } from '../../types/auth';
import { User, PaymentStatus as UserPaymentStatus } from '../../entities/User';
import { Dictionary } from '../../entities/Dictionary';
import { createWxPaySDK } from '../../sdk/weixin/WxPaySDK';
import { wxPayConfig } from '../../config';
import * as crypto from 'crypto';
import { PaymentProofGenerator } from '../../utils/paymentProofGenerator';

/**
 * 将字符串金额转换为数字，避免精度损失
 * @param amount 金额字符串
 * @returns 金额数值（单位：元）
 */
function parseAmount(amount: string | number | undefined): number {
  if (amount === undefined || amount === null) return 0;
  
  // 如果是数字，直接返回
  if (typeof amount === 'number') return amount;
  
  // 移除所有非数字和小数点字符
  const cleanedAmount = amount.toString().replace(/[^\d.]/g, '');
  
  // 如果没有小数点，直接转换为数字
  if (!cleanedAmount.includes('.')) {
    return Number(cleanedAmount);
  }
  
  // 处理小数点
  const parts = cleanedAmount.split('.');
  const integerPart = parts[0];
  const decimalPart = parts[1].substring(0, 2).padEnd(2, '0'); // 保留两位小数
  
  // 组合整数部分和小数部分
  return Number(`${integerPart}.${decimalPart}`);
}

/**
 * 支付控制器 - APP端
 */
export class PaymentAppController {
  private paymentRepository: Repository<PaymentRecord>;
  private userRepository: Repository<User>;
  private dictionaryRepository: Repository<Dictionary>;
  private wxPaySDK;

  constructor() {
    this.paymentRepository = AppDataSource.getRepository(PaymentRecord);
    this.userRepository = AppDataSource.getRepository(User);
    this.dictionaryRepository = AppDataSource.getRepository(Dictionary);
    
    // 初始化微信支付SDK
    this.wxPaySDK = createWxPaySDK({
      appId: wxPayConfig.appId,
      appSecret: wxPayConfig.appSecret,
      mchId: wxPayConfig.mchId,
      mchKey: wxPayConfig.mchKey,
      notifyUrl: wxPayConfig.notifyUrl
    });
  }

  /**
   * 查询支付状态 - 查询当前用户的最新支付记录
   * 由于一个用户可能有多条支付记录，返回最新的一条
   */
  async getPaymentStatus(req: AuthRequest, res: Response) {
    try {
      const currentUser = req.user;

      if (!currentUser || !currentUser.id) {
        return res.status(401).json({
          success: false,
          message: '用户未登录'
        });
      }

      console.log(`查询用户 ${currentUser.id} 的最新支付记录`);

      // 查询支付记录，只查询当前用户的记录，并按创建时间降序排序获取最新的一条
      const paymentRecord = await this.paymentRepository.findOne({
        where: {
          userId: currentUser.id
        },
        order: {
          createTime: 'DESC', // 确保获取最新的一条记录
          id: 'DESC' // 如果创建时间相同，则按ID降序排序
        }
      });

      // 查询所有支付项目
      const allFeeItems = await this.dictionaryRepository.find({
        where: {
          type: 'FEE',
          enable: true
        },
        order: {
          id: 'ASC'
        }
      });

      // 处理所有支付项目的详细信息
      const feeItems = allFeeItems.map(item => {
        // 尝试解析 value 字段，如果是 JSON 格式的话
        let valueObj = null;
        try {
          valueObj = JSON.parse(item.value || '{}');
        } catch (e) {
          // 如果解析失败，使用原始值
          valueObj = { amount: item.value };
        }

        // 判断是否为当前用户选择的支付项目（如果有支付记录）
        const isSelected = paymentRecord ? 
          paymentRecord.paymentItem.split(',').includes(item.code || '') : 
          false;

        return {
          id: item.id,
          name: item.name,
          code: item.code,
          value: item.value,
          // 如果 value 是 JSON 格式，提取其中的字段
          amount: parseAmount(valueObj.amount),
          period: valueObj.period,
          description: valueObj.description || item.name,
          isSelected: isSelected // 标记是否为当前用户选择的支付项目
        };
      });

      // 如果没有找到支付记录，返回空数据和所有支付项目
      if (!paymentRecord) {
        console.log(`用户 ${currentUser.id} 没有支付记录`);
        return res.json({
          success: true,
          data: {
            orderNo: null,
            paymentItem: null,
            allPaymentItems: feeItems, // 所有支付项目
            amount: null,
            status: null,
            statusText: '未支付',
            paymentMethod: null,
            paymentMethodText: null,
            paymentTime: null,
            createTime: null,
            hasPaid: false
          }
        });
      }

      console.log(`找到用户 ${currentUser.id} 的最新支付记录，订单号: ${paymentRecord.orderNo}, 状态: ${paymentRecord.status}`);

      // 处理支付凭证URL，添加HOST前缀
      let paymentProofUrl = null;
      if (paymentRecord.paymentProof) {
        const appConfig = require('../../config/app').default;
        paymentProofUrl = `${appConfig.host}${paymentRecord.paymentProof}`;
        console.log(`支付凭证URL: ${paymentProofUrl}`);
      }

      // 返回支付状态信息
      return res.json({
        success: true,
        data: {
          orderNo: paymentRecord.orderNo,
          paymentItem: paymentRecord.paymentItem,
          allPaymentItems: feeItems, // 所有支付项目
          amount: paymentRecord.amount,
          status: paymentRecord.status,
          statusText: paymentRecord.statusText,
          paymentMethod: paymentRecord.paymentMethod,
          paymentMethodText: paymentRecord.paymentMethodText,
          paymentTime: paymentRecord.paymentTime,
          createTime: paymentRecord.createTime,
          hasPaid: paymentRecord.status === PaymentStatus.PAID,
          paymentProof: paymentRecord.paymentProof, // 原始相对路径
          paymentProofUrl: paymentProofUrl // 完整URL
        }
      });
    } catch (error: any) {
      console.error('查询支付状态失败:', error);
      return res.status(500).json({
        success: false,
        message: '查询支付状态失败',
        error: error.message
      });
    }
  }

  /**
   * 获取收费项目列表
   * 从 Dictionary 实体中获取类型为 FEE 的收费项目
   */
  async getFeeItems(req: Request, res: Response) {
    try {
      // 查询类型为 FEE 且启用状态的字典项
      const feeItems = await this.dictionaryRepository.find({
        where: {
          type: 'FEE',
          enable: true
        },
        order: {
          id: 'ASC'
        }
      });

      if (feeItems.length === 0) {
        return res.json({
          success: true,
          data: [],
          message: '暂无收费项目'
        });
      }

      // 处理返回数据
      const items = feeItems.map(item => {
        // 尝试解析 value 字段，如果是 JSON 格式的话
        let valueObj = null;
        try {
          valueObj = JSON.parse(item.value || '{}');
        } catch (e) {
          // 如果解析失败，直接使用原始值
          valueObj = { amount: item.value };
        }

        return {
          id: item.id,
          name: item.name,
          code: item.code,
          value: item.value,
          // 如果 value 是 JSON 格式，提取其中的字段
          amount: parseAmount(valueObj.amount),
          period: valueObj.period,
          description: valueObj.description || item.name
        };
      });

      return res.json({
        success: true,
        data: items
      });
    } catch (error: any) {
      console.error('获取收费项目失败:', error);
      return res.status(500).json({
        success: false,
        message: '获取收费项目失败',
        error: error.message
      });
    }
  }

  /**
   * 创建支付订单
   * 用于微信支付的统一下单接口
   */
  async createOrder(req: AuthRequest, res: Response) {
    // 创建查询运行器以支持事务
    const queryRunner = AppDataSource.createQueryRunner();
    
    // 开始事务
    await queryRunner.connect();
    await queryRunner.startTransaction();
    
    try {
      const currentUser = req.user;

      if (!currentUser || !currentUser.id) {
        console.error('创建支付订单失败: 用户未登录');
        return res.status(401).json({
          success: false,
          message: '用户未登录'
        });
      }

      // 从数据库中查询完整的用户信息，获取 wxOpenid
      const userInfo = await queryRunner.manager.findOne(User, {
        where: { id: currentUser.id }
      });

      if (!userInfo) {
        console.error(`创建支付订单失败: 用户 ${currentUser.id} 不存在`);
        await queryRunner.rollbackTransaction();
        await queryRunner.release();
        return res.status(404).json({
          success: false,
          message: '用户不存在'
        });
      }

      // 检查用户是否有 openid
      if (!userInfo.wxOpenid) {
        console.error(`创建支付订单失败: 用户 ${currentUser.id} 没有绑定微信账号，缺少 wxOpenid`);
        await queryRunner.rollbackTransaction();
        await queryRunner.release();
        return res.status(400).json({
          success: false,
          message: '您的账号未绑定微信，无法使用微信支付，请先绑定微信账号'
        });
      }

      console.log(`开始为用户 ${currentUser.id} 创建支付订单，openid: ${userInfo.wxOpenid}`);

      // 在事务中检查用户是否已有支付记录
      const existingPayment = await queryRunner.manager.findOne(PaymentRecord, {
        where: {
          userId: currentUser.id,
          status: PaymentStatus.PAID
        },
        lock: { mode: 'pessimistic_read' } // 使用悲观锁防止并发问题
      });

      if (existingPayment) {
        // 回滚事务并返回错误
        await queryRunner.rollbackTransaction();
        await queryRunner.release();
        
        console.warn(`用户 ${currentUser.id} 已有支付记录，订单号: ${existingPayment.orderNo}, 支付时间: ${existingPayment.paymentTime}`);
        return res.status(400).json({
          success: false,
          message: '您已经完成支付，无需重复支付'
        });
      }

      // 查询所有有效的支付项目
      const feeItems = await queryRunner.manager.find(Dictionary, {
        where: {
          type: 'FEE',
          enable: true
        },
        order: {
          id: 'ASC'
        }
      });

      if (feeItems.length === 0) {
        // 回滚事务并返回错误
        await queryRunner.rollbackTransaction();
        await queryRunner.release();
        
        console.error('创建支付订单失败: 暂无可用的支付项目');
        return res.status(404).json({
          success: false,
          message: '暂无可用的支付项目'
        });
      }

      console.log(`查询到 ${feeItems.length} 个有效支付项目`);

      // 计算总金额并收集项目信息
      let totalAmount = 0;
      const itemNames: string[] = [];
      const itemCodes: string[] = [];

      for (const item of feeItems) {
        // 解析支付金额
        let itemAmount = 0;
        try {
          const valueObj = JSON.parse(item.value || '{}');
          itemAmount = parseAmount(valueObj.amount);
        } catch (e) {
          // 如果解析失败，尝试直接转换
          itemAmount = parseAmount(item.value);
          console.warn(`解析支付项目 ${item.name} 的金额失败，使用直接转换: ${itemAmount}`);
        }

        if (itemAmount > 0) {
          totalAmount += itemAmount;
          itemNames.push(item.name || '');
          itemCodes.push(item.code || '');
          console.log(`添加支付项目: ${item.name}, 金额: ${itemAmount}`);
        }
      }

      // 确保金额精确到分
      totalAmount = Math.round(totalAmount * 100) / 100;

      if (totalAmount <= 0) {
        // 回滚事务并返回错误
        await queryRunner.rollbackTransaction();
        await queryRunner.release();
        
        console.error('创建支付订单失败: 支付金额无效，总金额为 0');
        return res.status(400).json({
          success: false,
          message: '支付金额无效'
        });
      }

      console.log(`计算得到总金额: ${totalAmount}元`);

      // 生成订单号
      const orderNo = this.generateOrderNo(currentUser.id);
      console.log(`生成订单号: ${orderNo}`);

      // 创建支付记录
      const paymentRecord = new PaymentRecord();
      paymentRecord.orderNo = orderNo;
      paymentRecord.userId = currentUser.id;
      paymentRecord.paymentItem = itemCodes.join(','); // 使用逗号分隔多个项目编码
      paymentRecord.description = itemNames.join('、'); // 使用顿号分隔多个项目名称
      paymentRecord.amount = totalAmount;
      paymentRecord.status = PaymentStatus.PENDING;
      paymentRecord.paymentMethod = PaymentMethod.WECHAT;
      paymentRecord.createdBy = currentUser.id;

      // 在事务中保存支付记录
      await queryRunner.manager.save(paymentRecord);
      console.log(`保存支付记录成功，订单号: ${orderNo}`);

      // 调用微信支付统一下单接口
      const totalFee = Math.round(totalAmount * 100); // 微信支付金额单位为分，确保为整数
      console.log(`调用微信支付统一下单接口，订单号: ${orderNo}, 金额: ${totalFee}分, openid: ${userInfo.wxOpenid}`);
      
      // 准备统一下单的参数
      const unifiedOrderParams = {
        openid: userInfo.wxOpenid,
        outTradeNo: orderNo,
        totalFee: totalFee,
        body: `${userInfo.name || '学费缴纳'} - 学费缴纳`,
        attach: JSON.stringify({
          userId: currentUser.id,
          itemCodes: itemCodes
        })
      };
      
      console.log('统一下单参数:', JSON.stringify(unifiedOrderParams));
      console.log('微信支付配置:', {
        appId: this.wxPaySDK['appId'],
        mchId: this.wxPaySDK['mchId'],
        notifyUrl: this.wxPaySDK['notifyUrl']
      });
      
      try {
        const result = await this.wxPaySDK.unifiedOrder(unifiedOrderParams);

        // 记录完整的返回结果（去除敏感信息）
        const logResult = { ...result };
        if (logResult.data) {
          logResult.data = { ...logResult.data };
          // 移除敏感信息
          if (logResult.data.paySign) logResult.data.paySign = '***';
        }
        console.log(`微信支付统一下单结果:`, JSON.stringify(logResult));

        // 检查结果中是否包含prepay_id，这是判断统一下单是否成功的关键
        const rawResponse = result.rawResponse || '';
        if (!result.success && rawResponse && rawResponse.includes('prepay_id') && rawResponse.includes('SUCCESS')) {
          console.log('检测到微信支付返回了prepay_id，但SDK判断为失败，尝试修正结果...');
          
          try {
            // 尝试从原始XML响应中提取prepay_id
            const prepayIdMatch = rawResponse.match(/<prepay_id>\s*<!\[CDATA\[(.*?)\]\]>\s*<\/prepay_id>/);
            const prepayId = prepayIdMatch ? prepayIdMatch[1] : null;
            
            if (prepayId) {
              console.log(`从原始响应中提取到prepay_id: ${prepayId}`);
              
              // 手动构建成功的结果
              const timeStamp = Math.floor(Date.now() / 1000).toString();
              const nonceStr = Math.random().toString(36).substring(2, 15);
              
              const payParams: Record<string, any> = {
                appId: this.wxPaySDK['appId'],
                timeStamp,
                nonceStr,
                package: `prepay_id=${prepayId}`,
                signType: 'MD5'
              };
              
              // 生成签名
              const paySign = this.wxPaySDK.generateSign(payParams);
              
              result.success = true;
              result.data = {
                timeStamp,
                nonceStr,
                package: payParams.package,
                signType: payParams.signType,
                paySign,
                orderId: unifiedOrderParams.outTradeNo,
                prepayId: prepayId
              };
              
              console.log('成功修正微信支付统一下单结果');
            }
          } catch (parseError) {
            console.error('尝试修正微信支付结果时出错:', parseError);
          }
        }

        if (!result.success) {
          // 如果下单失败，更新支付记录状态
          paymentRecord.status = PaymentStatus.FAILED;
          await queryRunner.manager.save(paymentRecord);
          
          // 提交事务（即使失败也要记录）
          await queryRunner.commitTransaction();
          await queryRunner.release();

          // 记录详细的错误信息，包括 result 对象的完整内容
          console.error(`微信支付统一下单失败，订单号: ${orderNo}`, {
            orderNo,
            userId: currentUser.id,
            amount: totalAmount,
            openid: userInfo.wxOpenid,
            errorResult: result, // 记录完整的结果对象
            errorMessage: result.errorMessage || '未知错误',
            errorCode: result.errorCode || '未知错误码',
            rawResponse: result.rawResponse || '无原始响应'
          });

          return res.status(500).json({
            success: false,
            message: '创建支付订单失败',
            error: result.errorMessage || '微信支付接口返回错误，请稍后再试'
          });
        }

        console.log(`微信支付统一下单成功，订单号: ${orderNo}`, {
          orderNo,
          prepayId: result.data?.prepayId,
          userId: currentUser.id,
          responseData: result.data
        });

        // 提交事务
        await queryRunner.commitTransaction();
        await queryRunner.release();

        // 返回支付参数
        return res.json({
          success: true,
          data: {
            ...result.data,
            orderNo: orderNo,
            amount: totalAmount,
            items: feeItems.map(item => {
              // 解析支付金额
              let itemAmount = 0;
              let valueObj: Record<string, any> = {};
              try {
                valueObj = JSON.parse(item.value || '{}');
                itemAmount = parseAmount(valueObj.amount);
              } catch (e) {
                itemAmount = parseAmount(item.value);
              }
              
              return {
                name: item.name,
                code: item.code,
                amount: itemAmount,
                description: valueObj.description || item.name
              };
            }).filter(item => item.amount > 0)
          }
        });
      } catch (wxPayError: any) {
        // 捕获微信支付SDK可能抛出的异常
        paymentRecord.status = PaymentStatus.FAILED;
        await queryRunner.manager.save(paymentRecord);
        
        // 提交事务（即使失败也要记录）
        await queryRunner.commitTransaction();
        await queryRunner.release();
        
        console.error(`微信支付统一下单异常，订单号: ${orderNo}`, {
          orderNo,
          userId: currentUser.id,
          amount: totalAmount,
          openid: userInfo.wxOpenid,
          error: wxPayError.message,
          stack: wxPayError.stack
        });
        
        return res.status(500).json({
          success: false,
          message: '创建支付订单失败',
          error: '微信支付接口异常，请稍后再试'
        });
      }
    } catch (error: any) {
      // 发生错误时回滚事务
      await queryRunner.rollbackTransaction();
      await queryRunner.release();
      
      // 详细记录错误信息
      console.error('创建支付订单失败:', {
        error: error.message,
        stack: error.stack,
        userId: req.user?.id,
        time: new Date().toISOString()
      });
      
      return res.status(500).json({
        success: false,
        message: '创建支付订单失败',
        error: error.message
      });
    }
  }

  /**
   * 查询订单状态
   * 用于查询微信支付订单状态
   */
  async queryOrderStatus(req: AuthRequest, res: Response) {
    try {
      const currentUser = req.user;

      if (!currentUser || !currentUser.id) {
        return res.status(401).json({
          success: false,
          message: '用户未登录'
        });
      }

      const { orderNo } = req.params;

      if (!orderNo) {
        return res.status(400).json({
          success: false,
          message: '缺少订单号'
        });
      }

      // 查询本地支付记录
      const paymentRecord = await this.paymentRepository.findOne({
        where: {
          orderNo: orderNo,
          userId: currentUser.id
        }
      });

      if (!paymentRecord) {
        return res.status(404).json({
          success: false,
          message: '订单不存在'
        });
      }

      // 如果本地订单状态已经是已支付，直接返回
      if (paymentRecord.status === PaymentStatus.PAID) {
        // 处理支付凭证URL，添加HOST前缀
        let paymentProofUrl = null;
        if (paymentRecord.paymentProof) {
          const appConfig = require('../../config/app').default;
          paymentProofUrl = `${appConfig.host}${paymentRecord.paymentProof}`;
        }

        return res.json({
          success: true,
          data: {
            orderNo: paymentRecord.orderNo,
            status: paymentRecord.status,
            statusText: paymentRecord.statusText,
            paymentTime: paymentRecord.paymentTime,
            transactionId: paymentRecord.transactionId,
            paymentProof: paymentRecord.paymentProof, // 原始相对路径
            paymentProofUrl: paymentProofUrl // 完整URL
          }
        });
      }

      // 调用微信支付查询订单接口
      const result = await this.wxPaySDK.queryOrder(orderNo);

      if (!result.success) {
        return res.status(500).json({
          success: false,
          message: '查询订单状态失败',
          error: result.errorMessage
        });
      }

      // 如果微信支付显示已支付，但本地状态不是已支付，则更新本地状态
      if (result.data.tradeState === 'SUCCESS' && paymentRecord.status as number !== PaymentStatus.PAID) {
        // 创建查询运行器以支持事务
        const queryRunner = AppDataSource.createQueryRunner();
        
        // 开始事务
        await queryRunner.connect();
        await queryRunner.startTransaction();
        
        try {
          // 在事务中更新支付记录
          paymentRecord.status = PaymentStatus.PAID;
          paymentRecord.paymentTime = new Date();
          paymentRecord.transactionId = result.data.transactionId;
          paymentRecord.updatedBy = currentUser.id;
          
          await queryRunner.manager.save(paymentRecord);
          console.log(`订单 ${orderNo} 已更新为已支付状态`);
          
          // 在事务中更新用户缴费状态
          const user = await queryRunner.manager.findOne(User, {
            where: { id: currentUser.id }
          });
          
          if (user) {
            // 更新用户缴费状态
            user.paymentStatus = UserPaymentStatus.PAID; // 已缴费
            user.updatedBy = currentUser.id;
            
            await queryRunner.manager.save(user);
            console.log(`用户 ${currentUser.id} 的缴费状态已更新为已缴费`);
          } else {
            console.error(`用户不存在: ${currentUser.id}`);
          }
          
          // 提交事务
          await queryRunner.commitTransaction();
          console.log(`订单 ${orderNo} 处理完成，事务已提交`);
        } catch (txError: any) {
          // 发生错误时回滚事务
          await queryRunner.rollbackTransaction();
          console.error(`处理订单 ${orderNo} 时事务出错，已回滚:`, txError);
        } finally {
          // 释放查询运行器
          await queryRunner.release();
        }
      }

      // 返回订单状态
      return res.json({
        success: true,
        data: {
          orderNo: paymentRecord.orderNo,
          status: paymentRecord.status,
          statusText: paymentRecord.statusText,
          paymentTime: paymentRecord.paymentTime,
          transactionId: paymentRecord.transactionId,
          wxPayStatus: result.data.tradeState,
          wxPayStatusDesc: result.data.tradeStateDesc,
          paymentProof: paymentRecord.paymentProof, // 原始相对路径
          paymentProofUrl: paymentRecord.paymentProof ? `${require('../../config/app').default.host}${paymentRecord.paymentProof}` : null // 完整URL
        }
      });
    } catch (error: any) {
      console.error('查询订单状态失败:', error);
      return res.status(500).json({
        success: false,
        message: '查询订单状态失败',
        error: error.message
      });
    }
  }

  /**
   * 处理微信支付回调通知
   */
  async handlePayNotify(req: Request, res: Response) {
    try {
      console.log('收到微信支付回调通知');
      
      // 获取原始XML数据
      const xmlData = req.body;
      
      // 检查数据类型并记录
      console.log('回调通知数据类型:', typeof xmlData);
      
      // 确保xmlData是字符串类型
      let xmlString: string;
      if (typeof xmlData === 'string') {
        xmlString = xmlData;
        console.log('回调通知数据预览:', xmlString.substring(0, 200) + (xmlString.length > 200 ? '...' : ''));
      } else if (xmlData && typeof xmlData === 'object') {
        // 如果是对象（可能是已解析的XML或Buffer），尝试转换为字符串
        try {
          if (Buffer.isBuffer(xmlData)) {
            xmlString = xmlData.toString('utf8');
          } else if (xmlData.toString) {
            xmlString = xmlData.toString();
          } else {
            // 如果是已解析的对象，可能需要重新序列化为XML
            xmlString = JSON.stringify(xmlData);
            console.warn('接收到的数据不是XML字符串，已尝试转换:', xmlString.substring(0, 200));
          }
        } catch (convError) {
          console.error('转换XML数据失败:', convError);
          return res.send(this.wxPaySDK.generateNotifyResponse(false));
        }
      } else {
        console.error('支付回调通知数据无效:', xmlData);
        return res.send(this.wxPaySDK.generateNotifyResponse(false));
      }

      if (!xmlString) {
        console.error('支付回调通知数据为空');
        return res.send(this.wxPaySDK.generateNotifyResponse(false));
      }

      // 解析支付通知数据
      const result = this.wxPaySDK.parsePayNotify(xmlString);
      console.log('解析支付通知结果:', result.success ? '成功' : '失败', result.errorMessage || '');

      if (!result.success) {
        console.error('解析支付通知失败:', result.errorMessage);
        return res.send(this.wxPaySDK.generateNotifyResponse(false));
      }

      const { outTradeNo, transactionId, totalFee, timeEnd, attach } = result.data;
      console.log('解析后的支付通知数据:', {
        outTradeNo, 
        transactionId, 
        totalFee, 
        timeEnd,
        attach: attach ? attach.substring(0, 100) : '无附加数据'
      });

      // 创建查询运行器以支持事务
      const queryRunner = AppDataSource.createQueryRunner();
      
      // 开始事务
      await queryRunner.connect();
      await queryRunner.startTransaction();
      
      try {
        // 查询支付记录
        const paymentRecord = await queryRunner.manager.findOne(PaymentRecord, {
          where: {
            orderNo: outTradeNo
          },
          lock: { mode: 'pessimistic_write' } // 使用悲观锁防止并发问题
        });

        if (!paymentRecord) {
          console.error('支付记录不存在:', outTradeNo);
          await queryRunner.rollbackTransaction();
          return res.send(this.wxPaySDK.generateNotifyResponse(false));
        }

        // 验证支付金额
        const orderAmount = Math.round(paymentRecord.amount * 100); // 确保转换为整数分
        if (orderAmount !== totalFee) {
          console.error('支付金额不匹配:', orderAmount, totalFee);
          await queryRunner.rollbackTransaction();
          return res.send(this.wxPaySDK.generateNotifyResponse(false));
        }

        // 如果支付记录已经是已支付状态，直接返回成功
        if (paymentRecord.status === PaymentStatus.PAID) {
          console.log(`订单 ${outTradeNo} 已经是已支付状态，直接返回成功`);
          await queryRunner.rollbackTransaction();
          return res.send(this.wxPaySDK.generateNotifyResponse(true));
        }

        // 处理支付时间
        let paymentTime: Date;
        try {
          if (timeEnd) {
            // 确保 timeEnd 是字符串
            const timeEndStr = timeEnd.toString();
            console.log(`原始支付时间字符串: ${timeEndStr}, 长度: ${timeEndStr.length}, 类型: ${typeof timeEnd}`);
            
            if (timeEndStr.length === 14) {
              const year = timeEndStr.substring(0, 4);
              const month = timeEndStr.substring(4, 6);
              const day = timeEndStr.substring(6, 8);
              const hour = timeEndStr.substring(8, 10);
              const minute = timeEndStr.substring(10, 12);
              const second = timeEndStr.substring(12, 14);
              
              const dateStr = `${year}-${month}-${day}T${hour}:${minute}:${second}`;
              console.log(`解析支付时间: ${timeEndStr} -> ${dateStr}`);
              
              paymentTime = new Date(dateStr);
              
              // 验证日期是否有效
              if (isNaN(paymentTime.getTime())) {
                throw new Error(`无效的日期: ${dateStr}`);
              }
              
              console.log(`支付时间解析成功: ${paymentTime.toISOString()}`);
            } else {
              throw new Error(`无效的时间格式长度: ${timeEndStr}`);
            }
          } else {
            throw new Error('支付时间为空');
          }
        } catch (error: any) {
          console.error(`解析支付时间失败: ${timeEnd}`, error);
          paymentTime = new Date(); // 使用当前时间作为备选
          console.log(`使用当前时间作为支付时间: ${paymentTime.toISOString()}`);
        }

        // 更新支付记录状态
        paymentRecord.status = PaymentStatus.PAID;
        paymentRecord.transactionId = transactionId;
        paymentRecord.paymentTime = paymentTime;
        
        // 解析附加数据
        let userId = 'system';
        try {
          if (attach) {
            const attachData = JSON.parse(attach);
            if (attachData.userId) {
              userId = attachData.userId;
              paymentRecord.updatedBy = userId;
            }
          }
        } catch (e) {
          console.error('解析附加数据失败:', e);
          paymentRecord.updatedBy = 'system';
        }

        console.log(`更新订单 ${outTradeNo} 状态为已支付，支付时间: ${paymentTime.toISOString()}`);
        
        // 生成支付凭证
        try {
          const paymentProofPath = await this.generatePaymentProof(paymentRecord, userId);
          paymentRecord.paymentProof = paymentProofPath;
          console.log(`生成支付凭证成功: ${paymentProofPath}`);
        } catch (error: any) {
          console.error('生成支付凭证失败:', error);
          // 即使生成凭证失败，也继续处理支付流程
        }
        
        // 在事务中保存支付记录
        await queryRunner.manager.save(paymentRecord);
        console.log(`订单 ${outTradeNo} 已更新为已支付状态`);

        // 在事务中更新用户缴费状态
        const user = await queryRunner.manager.findOne(User, {
          where: { id: paymentRecord.userId }
        });
        
        if (user) {
          // 更新用户缴费状态
          user.paymentStatus = UserPaymentStatus.PAID; // 已缴费
          user.updatedBy = userId;
          
          await queryRunner.manager.save(user);
          console.log(`用户 ${paymentRecord.userId} 的缴费状态已更新为已缴费`);
        } else {
          console.error(`用户不存在: ${paymentRecord.userId}`);
        }
        
        // 提交事务
        await queryRunner.commitTransaction();
        console.log(`处理支付回调完成，事务已提交`);

        // 返回成功响应
        console.log(`处理支付回调完成，返回成功响应`);
        return res.send(this.wxPaySDK.generateNotifyResponse(true));
      } catch (txError: any) {
        // 发生错误时回滚事务
        await queryRunner.rollbackTransaction();
        console.error('处理支付回调通知失败:', txError);
        return res.send(this.wxPaySDK.generateNotifyResponse(false));
      } finally {
        // 释放查询运行器
        await queryRunner.release();
      }
    } catch (error: any) {
      console.error('处理支付回调通知失败:', error);
      return res.send(this.wxPaySDK.generateNotifyResponse(false));
    }
  }

  /**
   * 生成支付凭证
   * @param paymentRecord 支付记录
   * @param userId 用户ID
   * @returns 支付凭证路径
   */
  private async generatePaymentProof(paymentRecord: PaymentRecord, userId: string): Promise<string> {
    try {
      // 获取用户信息
      const user = await this.userRepository.findOne({
        where: { id: paymentRecord.userId }
      });
      
      // 使用统一的支付凭证生成器
      return await PaymentProofGenerator.generatePaymentProof(paymentRecord, user || undefined);
    } catch (error: any) {
      console.error('生成支付凭证失败:', error);
      throw error;
    }
  }

  /**
   * 更新用户缴费状态
   * @param userId 用户ID
   */
  private async updateUserPaymentStatus(userId: string): Promise<void> {
    // 创建查询运行器以支持事务
    const queryRunner = AppDataSource.createQueryRunner();
    
    // 开始事务
    await queryRunner.connect();
    await queryRunner.startTransaction();
    
    try {
      const user = await queryRunner.manager.findOne(User, {
        where: { id: userId }
      });

      if (!user) {
        console.error('用户不存在:', userId);
        await queryRunner.rollbackTransaction();
        return;
      }

      // 更新用户缴费状态
      user.paymentStatus = UserPaymentStatus.PAID; // 已缴费
      user.updatedBy = userId;
      
      await queryRunner.manager.save(user);
      console.log(`用户 ${userId} 的缴费状态已更新为已缴费`);
      
      // 提交事务
      await queryRunner.commitTransaction();
    } catch (error) {
      // 发生错误时回滚事务
      await queryRunner.rollbackTransaction();
      console.error('更新用户缴费状态失败:', error);
    } finally {
      // 释放查询运行器
      await queryRunner.release();
    }
  }

  /**
   * 生成订单号
   * @param userId 用户ID
   */
  private generateOrderNo(userId: string): string {
    // 生成格式为：年月日时分秒 + 用户ID后6位 + 4位随机数
    const now = new Date();
    const dateStr = 
      now.getFullYear().toString() +
      this.padZero(now.getMonth() + 1) +
      this.padZero(now.getDate()) +
      this.padZero(now.getHours()) +
      this.padZero(now.getMinutes()) +
      this.padZero(now.getSeconds());
    
    // 获取用户ID的后6位，不足6位则前面补0
    const userIdSuffix = userId.substring(Math.max(0, userId.length - 6)).padStart(6, '0');
    
    // 生成4位随机数
    const randomNum = Math.floor(Math.random() * 10000).toString().padStart(4, '0');
    
    return dateStr + userIdSuffix + randomNum;
  }

  /**
   * 数字补零
   * @param num 数字
   */
  private padZero(num: number): string {
    return num < 10 ? `0${num}` : num.toString();
  }

  /**
   * 查询用户最新的支付记录并关联支付项目
   * 可以查询指定用户的最新支付记录，或者当前登录用户的记录
   */
  async getUserPaymentRecord(req: AuthRequest, res: Response) {
    try {
      const currentUser = req.user;
      
      // 检查用户是否已登录
      if (!currentUser || !currentUser.id) {
        return res.status(401).json({
          success: false,
          message: '用户未登录'
        });
      }
      
      // 获取请求中的用户ID，如果没有提供则使用当前用户ID
      let targetUserId =  currentUser.id;
      
      // 如果当前用户不是管理员，只允许查询自己的记录
      if (targetUserId !== currentUser.id && currentUser.role !== 'admin') {
        console.warn(`用户 ${currentUser.id} 尝试查询用户 ${targetUserId} 的支付记录，权限不足`);
        targetUserId = currentUser.id; // 将目标用户ID重置为当前用户ID
      }
      
      console.log(`查询用户 ${targetUserId} 的最新支付记录`);
      
      // 查询目标用户的支付记录，按创建时间降序排序获取最新的记录
      const paymentRecords = await this.paymentRepository.find({
        where: {
          userId: targetUserId
        },
        order: {
          createTime: 'DESC',
          id: 'DESC'
        },
        take: 5 // 获取最新的5条记录
      });
      
      // 如果没有找到支付记录，返回空数据
      if (!paymentRecords || paymentRecords.length === 0) {
        console.log(`用户 ${targetUserId} 没有支付记录`);
        return res.json({
          success: true,
          message: '没有找到支付记录',
          data: {
            user: {
              id: targetUserId
            },
            paymentRecords: []
          }
        });
      }
      
      // 获取用户信息
      const user = await this.userRepository.findOne({
        where: { id: targetUserId }
      });
      
      if (!user) {
        return res.status(404).json({
          success: false,
          message: '用户不存在'
        });
      }
      
      // 获取所有支付项目代码
      const allItemCodes = new Set<string>();
      paymentRecords.forEach(record => {
        if (record.paymentItem) {
          record.paymentItem.split(',').forEach(code => {
            if (code.trim()) {
              allItemCodes.add(code.trim());
            }
          });
        }
      });
      
      // 查询所有相关的支付项目
      const codeArray = Array.from(allItemCodes);
      const feeItems = await this.dictionaryRepository.find({
        where: {
          type: 'FEE',
          // 使用 In 操作符查询多个编码
          code: codeArray.length > 0 ? In(codeArray) : undefined
        }
      });
      
      // 创建支付项目查找映射
      const feeItemMap = new Map();
      feeItems.forEach(item => {
        // 解析项目值对象
        let valueObj: { 
          amount?: number | string;
          period?: string;
          description?: string;
          [key: string]: any;
        } = {};
        
        try {
          valueObj = JSON.parse(item.value || '{}');
        } catch (e) {
          valueObj = { amount: parseAmount(item.value) };
        }
        
        feeItemMap.set(item.code, {
          id: item.id,
          name: item.name,
          code: item.code,
          value: item.value,
          amount: parseAmount(valueObj.amount),
          period: valueObj.period || '',
          description: valueObj.description || item.name
        });
      });
      
      // 处理支付记录，添加支付项目详细信息
      const processedRecords = paymentRecords.map(record => {
        const itemCodes = record.paymentItem ? record.paymentItem.split(',') : [];
        const itemDetails = itemCodes.map(code => {
          return feeItemMap.get(code) || {
            code,
            name: '未知项目',
            amount: 0
          };
        });
        
        // 处理支付凭证URL
        let paymentProofUrl = null;
        if (record.paymentProof) {
          const appConfig = require('../../config/app').default;
          paymentProofUrl = `${appConfig.host}${record.paymentProof}`;
        }
        
        return {
          id: record.id,
          orderNo: record.orderNo,
          amount: record.amount,
          status: record.status,
          statusText: record.statusText,
          paymentMethod: record.paymentMethod,
          paymentMethodText: record.paymentMethodText,
          paymentTime: record.paymentTime,
          transactionId: record.transactionId,
          createTime: record.createTime,
          description: record.description,
          paymentProof: record.paymentProof,
          paymentProofUrl: paymentProofUrl,
          hasPaid: record.status === PaymentStatus.PAID,
          paymentItems: itemDetails // 关联的支付项目详细信息
        };
      });
      
      // 构建用户基本信息，只包含已知存在的字段
      const userInfo = {
        id: user.id,
        name: user.name || '',
        // 只包含用户实体中存在的字段
        mobile: user.mobile || '',
        idCard: user.idCard || '',
        paymentStatus: user.paymentStatus
      };
      
      // 返回处理后的数据
      return res.json({
        success: true,
        data: {
          user: userInfo,
          paymentRecords: processedRecords
        }
      });
      
    } catch (error: any) {
      console.error('查询用户支付记录失败:', error);
      return res.status(500).json({
        success: false,
        message: '查询用户支付记录失败',
        error: error.message
      });
    }
  }
}

// 导出控制器实例
export const paymentAppController = new PaymentAppController(); 